package com.qihunet.tplus.productimport.Service;

import com.qihunet.tplus.productimport.entity.*;
import com.qihunet.tplus.productimport.utils.ReflectionUtils;
import com.qihunet.tplus.productimport.utils.ResultCode;
import com.qihunet.tplus.productimport.utils.ResultInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
public class CostAllocationOrderService {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private SystemConfig systemConfig;

    /**
     * 获取所有的生产加工单DTO
     * @return
     */
    public List<ManufactureOrder> getAllManufactureOrder(){
        String sql="select id,code from MP_ManufactureOrder where voucherstate=189";
        return (List<ManufactureOrder>) jdbcTemplate.query(sql, new RowMapper<ManufactureOrder>(){
            @Override
            public ManufactureOrder mapRow(ResultSet rs, int rowNum) throws SQLException {
                ResultSetMetaData rSetMetaData=rs.getMetaData();
                Map<String, Object> maps=new HashMap<String, Object>();
                ManufactureOrder manufactureOrder = new ManufactureOrder();
                for(int i=0;i<rSetMetaData.getColumnCount();i++){
                    String columnLabel=rSetMetaData.getColumnLabel(i+1);
                    Object columnValue=rs.getObject(i+1);
                    maps.put(columnLabel,columnValue);
                }
                if(maps.size()>0){
                    for(Map.Entry<String,Object> entry:maps.entrySet()){
                        String fieldName=entry.getKey();
                        Object fieldValue=entry.getValue();
                        ReflectionUtils.setFieldValue(manufactureOrder, fieldName, fieldValue);
                    }
                }
                return manufactureOrder;
            }
        });
    }

    /**
     *获取所有的生产加工单明细DTO
     * @return
     */
    public List<ManufactureOrderDetails> getAllManufactureOrderDetails(){
        String sql="select id,idManufactureOrderDTO,idInventory from MP_ManufactureOrder_b";
        return (List<ManufactureOrderDetails>) jdbcTemplate.query(sql, new RowMapper<ManufactureOrderDetails>(){
            @Override
            public ManufactureOrderDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
                ResultSetMetaData rSetMetaData=rs.getMetaData();
                Map<String, Object> maps=new HashMap<String, Object>();
                ManufactureOrderDetails manufactureOrderDetails = new ManufactureOrderDetails();
                for(int i=0;i<rSetMetaData.getColumnCount();i++){
                    String columnLabel=rSetMetaData.getColumnLabel(i+1);
                    Object columnValue=rs.getObject(i+1);
                    maps.put(columnLabel,columnValue);
                }
                if(maps.size()>0){
                    for(Map.Entry<String,Object> entry:maps.entrySet()){
                        String fieldName=entry.getKey();
                        Object fieldValue=entry.getValue();
                        ReflectionUtils.setFieldValue(manufactureOrderDetails, fieldName, fieldValue);
                    }
                }
                return manufactureOrderDetails;
            }
        });
    }

    /**
     * 获取成品入库明细信息
     * @param
     * @return
     */
    public List<RDRecordDetailDTO> getRDRecordDetailInfo(String rkdCode){
        String sql=String.format("select TOP 1000 [Warehouse].code as Warehouse_Code," +
                "[RDRecordDetailDTO].price AS refcost,[RDRecordDetailDTO].amount AS totalrefcost," +
                "[RDRecordDetailDTO].sourceVoucherCode AS jgdCode, [RDRecordDetailDTO].manufactureOrderDetailid AS jgdDetailId,[RDRecordDetailDTO].manufactureOrderid as jgdId,[BaseUnit].code as BaseUnit_Code,[RDRecordDetailDTO].id AS ID,[Warehouse].name AS Warehouse_Name," +
                "[Inventory].code AS Inventory_Code,[Inventory].name AS Inventory_Name,[Inventory].specification AS Inventory_Specification," +
                "[BaseUnit].name AS BaseUnit_Name,[RDRecordDetailDTO].baseQuantity AS baseQuantity," +
                "[SourceVoucherType].name AS SourceVoucherType_Name,[RDRecordDetailDTO].idRDRecordDTO AS idRDRecordDTO," +
                "[RDRecord].code AS RDRecord_Code,[RDRecordDetailDTO].code AS Code,[SourceVoucherType].id as SourceVoucherType_id," +
                "[RDRecord].id as RDRecord_id,[Inventory].id as Inventory_id,[BaseUnit].id as BaseUnit_id," +
                "[Warehouse].id as Warehouse_id" +
                " from [ST_RDRecord_b] [RDRecordDetailDTO]" +
                " LEFT OUTER JOIN [SM_VoucherType] [SourceVoucherType] on [RDRecordDetailDTO].idsourcevouchertype=[SourceVoucherType].id" +
                " LEFT OUTER JOIN [ST_RDRecord] [RDRecord] on [RDRecordDetailDTO].idRDRecordDTO=[RDRecord].id" +
                " LEFT OUTER JOIN [AA_Inventory] [Inventory] on [RDRecordDetailDTO].idinventory=[Inventory].id" +
                " LEFT OUTER JOIN [AA_Unit] [BaseUnit] on [RDRecordDetailDTO].idbaseunit=[BaseUnit].id" +
                " LEFT OUTER JOIN [AA_Warehouse] [Warehouse] on [RDRecordDetailDTO].idwarehouse=[Warehouse].id" +
                " where [Warehouse].Disabled=0 AND [Inventory].Disabled=0 And [RDRecord].VoucherState= N'189' And 1=1 and 1=1" +
                " And ([RDRecord].sourceVoucherCode='%s')" +
                " and not exists (select 1 from MP_CostAllocationOrder_src where RDRecordDetailDTO.Id = MP_CostAllocationOrder_src.rkdDetailId)" +
                " and ([RDRecord].idVoucherType= N'15') order by [RDRecord].Code, RDRecordDetailDTO.Code",rkdCode);
        return (List<RDRecordDetailDTO>) jdbcTemplate.query(sql, new RowMapper<RDRecordDetailDTO>(){
            @Override
            public RDRecordDetailDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
                ResultSetMetaData rSetMetaData=rs.getMetaData();
                Map<String, Object> maps=new HashMap<String, Object>();
                RDRecordDetailDTO detailDTO = new RDRecordDetailDTO();
                for(int i=0;i<rSetMetaData.getColumnCount();i++){
                    String columnLabel=rSetMetaData.getColumnLabel(i+1);
                    Object columnValue=rs.getObject(i+1);
                    maps.put(columnLabel,columnValue);
                }
                if(maps.size()>0){
                    for(Map.Entry<String,Object> entry:maps.entrySet()){
                        String fieldName=entry.getKey();
                        Object fieldValue=entry.getValue();
                        ReflectionUtils.setFieldValue(detailDTO, fieldName, fieldValue);
                    }
                }
                return detailDTO;
            }
        });
    }

    /**
     *  产品成本分配明细表临时表
     * @return
     */
    public List<CostAllocationOrder_B_tmp> getCostAllocationOrder_B_tmpInfo(){
        //获取临时表信息
       String  sql=String.format("SELECT id,code,rkdcode,rkdid,jgdcode,jgdid,refcost,quantity,totalrefcost,idbaseunit,"
                +"idinventory,idwarehouse,SourceVoucherTypeId "+
                "FROM MP_CostAllocationOrder_b_tmp WHERE CurrUserID=%d ORDER BY code",systemConfig.getUserid());
        return (List<CostAllocationOrder_B_tmp>) jdbcTemplate.query(sql, new RowMapper<CostAllocationOrder_B_tmp>(){
            @Override
            public CostAllocationOrder_B_tmp mapRow(ResultSet rs, int rowNum) throws SQLException {
                ResultSetMetaData rSetMetaData=rs.getMetaData();
                Map<String, Object> maps=new HashMap<String, Object>();
                CostAllocationOrder_B_tmp detailDTO = new CostAllocationOrder_B_tmp();
                for(int i=0;i<rSetMetaData.getColumnCount();i++){
                    String columnLabel=rSetMetaData.getColumnLabel(i+1);
                    Object columnValue=rs.getObject(i+1);
                    maps.put(columnLabel,columnValue);
                }
                if(maps.size()>0){
                    for(Map.Entry<String,Object> entry:maps.entrySet()){
                        String fieldName=entry.getKey();
                        Object fieldValue=entry.getValue();
                        ReflectionUtils.setFieldValue(detailDTO, fieldName, fieldValue);
                    }
                }
                return detailDTO;
            }
        });
    }

    public void runPDSQL(String sql,Map<String,Object> paramMap){
        jdbcTemplate.execute(sql, new CallableStatementCallback<Object>() {
            @Override
            public Object doInCallableStatement(CallableStatement callableStatement) throws SQLException, DataAccessException {
                for(String key:paramMap.keySet()){
                    callableStatement.setObject(key,paramMap.get(key));
                }
                callableStatement.execute();
                return null;
            }
        });
    }

    /**
     * 插入数据到产品成本分配明细表临时表
     * @param rdRecordDetailDTOS
     */
    public void insertTOMP_CostAllocationOrder_b_tmp(java.util.Date orderDate, List<RDRecordDetailDTO> rdRecordDetailDTOS,
                                                      List<CostAllocationOrderDetails> costAllocationOrderDetailsList,
                                                      CostAllocationOrder costAllocationOrder){
        String sql=String.format("delete from MP_CostAllocationOrder_b_tmp where currUserId=%d and idCostAllocationOrderDTO<>%d",systemConfig.getUserid(),costAllocationOrder.getId());
        jdbcTemplate.execute(sql);

        sql = "INSERT INTO MP_CostAllocationOrder_b_tmp" +
                "(code, refcost, totalrefcost, quantity, directmaterials, indirectmaterials," +
                " manufacturecost, mancost, othercost, totalcost, " +
                "unitcost, jgdcode,idinventory, " +
                " idbaseunit, idCostAllocationOrderDTO, jgdid, " +
                "jgdDetailId, createdtime, SourceVoucherTypeId,currUserId)" +
                "VALUES( ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
        List<Object[]> params=new ArrayList<>();

        for(RDRecordDetailDTO data:rdRecordDetailDTOS){
            CostAllocationOrderDetails costAllocationOrderDetailsTemp=costAllocationOrderDetailsList.stream().filter(new Predicate<CostAllocationOrderDetails>() {
                @Override
                public boolean test(CostAllocationOrderDetails costAllocationOrderDetails) {
                    return costAllocationOrderDetails.getJgdcode().equals(data.getJgdCode())
                            && costAllocationOrderDetails.getIdinventory().intValue()==data.getInventory_id().intValue() ;
                }
            }).findFirst().get();
            Object[] childParams=new Object[20];
            childParams[0]=data.getCode();
            childParams[1]=data.getRefcost().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[2]=data.getTotalrefcost().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[3]=data.getBaseQuantity().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[4]=costAllocationOrderDetailsTemp.getDirectmaterials().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[5]=costAllocationOrderDetailsTemp.getIndirectmaterials().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[6]=costAllocationOrderDetailsTemp.getManufacturecost().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[7]=costAllocationOrderDetailsTemp.getMancost().setScale(2, BigDecimal.ROUND_HALF_UP);
            //childParams[4]=costAllocationOrderDetailsTemp.getOutsourcingcost().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[8]=costAllocationOrderDetailsTemp.getOthercost().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[9]=costAllocationOrderDetailsTemp.getTotalcost().setScale(2, BigDecimal.ROUND_HALF_UP);

            childParams[10]=costAllocationOrderDetailsTemp.getUnitcost().setScale(3, BigDecimal.ROUND_HALF_UP);

            childParams[11]=data.getJgdCode();
            childParams[12]=data.getInventory_id();
            childParams[13]=data.getBaseUnit_id();
            childParams[14]=costAllocationOrder.getId();
            childParams[15]=data.getJgdId();
            childParams[16]=data.getJgdDetailId();
            childParams[17]=orderDate;
            childParams[18]=15;
            childParams[19]=systemConfig.getUserid();
            params.add(childParams);
        }
        int[] falgs= jdbcTemplate.batchUpdate(sql,params);

        //插入来源
        sql=String.format("delete from MP_CostAllocationOrder_src_tmp where currUserId=%d and voucherid<>%d",systemConfig.getUserid(),costAllocationOrder.getId());
        jdbcTemplate.execute(sql);

        sql = "INSERT INTO MP_CostAllocationOrder_src_tmp" +
                "(currUserId,refcost, totalrefcost, quantity, jgdcode, rkdcode,idinventory, " +
                " idbaseunit,voucherid, idCostAllocationOrderDTO, jgdid, " +
                "jgdDetailId,rkdid, SourceVoucherId,rkdDetailid,SourceVoucherDetailId,createdtime,SourceVoucherTypeId,sourceVoucherCode)" +
                "VALUES( ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
        params=new ArrayList<>();

        for(RDRecordDetailDTO data:rdRecordDetailDTOS){
            CostAllocationOrderDetails costAllocationOrderDetailsTemp=costAllocationOrderDetailsList.stream().filter(new Predicate<CostAllocationOrderDetails>() {
                @Override
                public boolean test(CostAllocationOrderDetails costAllocationOrderDetails) {
                    return costAllocationOrderDetails.getJgdcode().equals(data.getJgdCode())
                            && costAllocationOrderDetails.getIdinventory().intValue()==data.getInventory_id().intValue() ;
                }
            }).findFirst().get();
            Object[] childParams=new Object[19];
            childParams[0]=systemConfig.getUserid();
            childParams[1]=data.getRefcost().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[2]=data.getTotalrefcost().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[3]=data.getBaseQuantity().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[4]=data.getJgdCode();
            childParams[5]=data.getRDRecord_Code();
            childParams[6]=data.getInventory_id();
            childParams[7]=data.getBaseUnit_id();

            childParams[8]=costAllocationOrder.getId();
            childParams[9]=costAllocationOrder.getId();
            childParams[10]=data.getJgdId();
            childParams[11]=data.getJgdDetailId();
            childParams[12]=data.getRDRecord_id();
            childParams[13]=data.getRDRecord_id();
            childParams[14]=data.getJgdDetailId();
            childParams[15]=data.getJgdDetailId();
            childParams[16]=orderDate;
            childParams[17]=data.getSourceVoucherType_id();
            childParams[18]=data.getRDRecord_Code();
            params.add(childParams);
        }
        falgs= jdbcTemplate.batchUpdate(sql,params);

    }


    /**
     * 保存数据
     * @return
     */
    @Transactional
    public ResultInfo<CostAllocationOrder> saveCostAllocationOrderInfo(Map<String,Object> excelMap){
        ResultInfo<CostAllocationOrder> resultInfo=new ResultInfo<>();
        resultInfo.setResultCode(ResultCode.ERROR);
        try {
            List<CostAllocationOrderDetails> costAllocationOrderDetailsList= (List<CostAllocationOrderDetails>) excelMap.get("orderData");
            String orderCode= (String) excelMap.get("code");
            java.util.Date orderDate= (java.util.Date) excelMap.get("date");

            Map<String,Object> hasMap=new HashMap<>();
            BigDecimal indirectmaterialcost=new BigDecimal(0);
            BigDecimal directmaterialcost=new BigDecimal(0);
            BigDecimal manufacturcost=new BigDecimal(0);
            BigDecimal mancost=new BigDecimal(0);
            BigDecimal othercost=new BigDecimal(0);

            CostAllocationOrder costAllocationOrder= createCostAllocationOrder(orderCode,orderDate,directmaterialcost,indirectmaterialcost,manufacturcost,mancost,othercost);
            if(costAllocationOrder==null){//插入失败
                throw new RuntimeException("插入主表失败");
            }else{

            }


            DecimalFormat df   = new DecimalFormat("0000");
            Integer num=0;

            String xml="";
            String costAllocationUpdateTmpXML="";
            String detailXML="";
            for (CostAllocationOrderDetails data:costAllocationOrderDetailsList) {

                indirectmaterialcost=data.getIndirectmaterials().add(indirectmaterialcost);
                directmaterialcost=data.getDirectmaterials().add(directmaterialcost);
                manufacturcost=data.getManufacturecost().add(manufacturcost);
                mancost=data.getMancost().add(mancost);
                othercost=data.getOthercost().add(othercost);

                if(hasMap.containsKey(data.getJgdcode())){
                    continue;
                }
                String sql=String.format("delete from MP_CostAllocationOrder_src where jgdcode='%s'",data.getJgdcode());
                jdbcTemplate.execute(sql);

                hasMap.put(data.getJgdcode(),"");
                //获取成品入库明细信息
                List<RDRecordDetailDTO> rdRecordDetailDTOS= getRDRecordDetailInfo(data.getJgdcode());



                for(RDRecordDetailDTO temp:rdRecordDetailDTOS){
                    xml=xml+String.format("<Row ID=\"%d\"/>",temp.getID());

                    CostAllocationOrderDetails dataTemp=costAllocationOrderDetailsList.stream().filter(
                            p->p.getJgdcode().equals(temp.getJgdCode())
                            && p.getIdinventory().intValue()==temp.getInventory_id()
                    ).findFirst().get();

                    costAllocationUpdateTmpXML=costAllocationUpdateTmpXML+
                            String.format("<Row ID=\"%d\" directmaterials='%f' indirectmaterials='%f' manufacturecost=\"%f\" " +
                                    "mancost=\"%f\" othercost=\"%f\" othercost1=\"0\" " +
                                    " othercost2=\"0\" totalcost=\"%f\" unitcost=\"%f\"/>",
                                    temp.getID(),
                                    dataTemp.getDirectmaterials().setScale(2, BigDecimal.ROUND_HALF_UP),
                                    dataTemp.getIndirectmaterials().setScale(2, BigDecimal.ROUND_HALF_UP),
                                    dataTemp.getManufacturecost().setScale(2, BigDecimal.ROUND_HALF_UP),
                                    dataTemp.getMancost().setScale(2, BigDecimal.ROUND_HALF_UP),
                                    dataTemp.getOthercost().setScale(2, BigDecimal.ROUND_HALF_UP),
                                    dataTemp.getTotalcost().setScale(2, BigDecimal.ROUND_HALF_UP),
                                    dataTemp.getUnitcost().setScale(3, BigDecimal.ROUND_HALF_UP));
                }


                insertTOMP_CostAllocationOrder_b_tmp(orderDate,rdRecordDetailDTOS,costAllocationOrderDetailsList,costAllocationOrder);

                //产品成本分配明细表临时表
                List<CostAllocationOrder_B_tmp> costAllocationOrder_b_tmps=getCostAllocationOrder_B_tmpInfo();


                for (CostAllocationOrder_B_tmp dataTemp:costAllocationOrder_b_tmps){
                    RDRecordDetailDTO rdRecordDetailDTOTemp =new RDRecordDetailDTO();
                    try {
                        rdRecordDetailDTOTemp = rdRecordDetailDTOS.stream().filter(new Predicate<RDRecordDetailDTO>() {
                            @Override
                            public boolean test(RDRecordDetailDTO rdRecordDetailDTO) {
                                return rdRecordDetailDTO.getJgdId().intValue() == dataTemp.getJgdid().intValue()
                                        && rdRecordDetailDTO.getInventory_id().intValue() == dataTemp.getIdinventory().intValue();
                            }
                        }).findFirst().get();
                    }catch (Exception ex){
                        //ex.printStackTrace();
                        //System.out.println("产品成本分配明细表临时表中找到对应数据，"+ex.getMessage());
                        continue;
                    }

                    detailXML=detailXML+String.format("<Row ID='%d' Code='%s' rkdCode='%s' rkdId='%d' jgdCode='%s" +
                            " jgdId='%d' refCost='%f' rkQty='%f' totalrefcost='%f' " +
                            " idBaseUnit='%d' idinventory='%d' " +
                            " tbatch='' idwarehouse='%d' SourceVoucherTypeId='%d' " +
                            " invCode='%s' invName='%s' invSpec='%s' baseUnitName='%s' baseUnitCode='%s' warehouseName='%s' warehouseCode='%s' />",
                            dataTemp.getId(),dataTemp.getCode(),dataTemp.getRkdcode()==null?"":dataTemp.getRkdcode(),
                            dataTemp.getRkdid()==null?0:dataTemp.getRkdid(),dataTemp.getJgdcode(),
                            dataTemp.getJgdid(),dataTemp.getRefcost().doubleValue(),dataTemp.getQuantity().doubleValue(),dataTemp.getTotalrefcost().doubleValue(),
                            dataTemp.getIdbaseunit(),dataTemp.getIdinventory(),dataTemp.getIdwarehouse(),dataTemp.getSourceVoucherTypeId(),
                            rdRecordDetailDTOTemp.getInventory_Code(),rdRecordDetailDTOTemp.getInventory_Name(),rdRecordDetailDTOTemp.getInventory_Specification(),
                            rdRecordDetailDTOTemp.getBaseUnit_Name(),rdRecordDetailDTOTemp.getBaseUnit_Code(),
                            rdRecordDetailDTOTemp.getWarehouse_Name(),rdRecordDetailDTOTemp.getWarehouse_Code());
                }

            }

            xml="<ROOT>"+xml+"</ROOT>";

//            String sql="{call MP_SP_CostAllocationOrderSel_isSumZero(?,?,?,?,?)}";
//
//            Map<String,Object> paramMap=new HashMap<>();
//            paramMap.put("voucherId",costAllocationOrder.getId());
//            paramMap.put("currUserID",systemConfig.getUserid());
//            paramMap.put("costCollectorObject","jgdInventory");
//            paramMap.put("selDetailsXml",xml);
//            paramMap.put("isHadSumQuantityZero",0);
//            runPDSQL(sql,paramMap);
//            paramMap.clear();
            Map<String,Object> paramMap=new HashMap<>();
            detailXML="<Details>"+detailXML+"</Details>";
            SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String sql="{call MP_SP_CostAllocationOrderSel(?,?,?,?,?)}";

            paramMap.put("voucherId",costAllocationOrder.getId());
            paramMap.put("currUserID",systemConfig.getUserid());
            paramMap.put("costCollectorObject","jgdInventory");
            paramMap.put("curVoucherDate",simpleDateFormat.format(orderDate));
            paramMap.put("selDetailsXml",xml);
            //paramMap.put("outDocXml",detailXML);
            runPDSQL(sql,paramMap);
            paramMap.clear();

//            sql="{call MP_SP_CostAllocationUpdateTmp(?,?)}";
//            costAllocationUpdateTmpXML="<ROOT>"+costAllocationUpdateTmpXML+"</ROOT>";
//            paramMap.put("DetailsXml",costAllocationUpdateTmpXML);
//            paramMap.put("currUserID",systemConfig.getUserid());
//            runPDSQL(sql,paramMap);
//            paramMap.clear();

            //更新主表
            sql=String.format("update MP_CostAllocationOrder set  directmaterialcost=%f," +
                    "indirectmaterialcost=%f, manufacturcost=%f, mancost=%f, othercost=%f where id=%d",
                    directmaterialcost.setScale(2, BigDecimal.ROUND_HALF_UP),
                    indirectmaterialcost.setScale(2, BigDecimal.ROUND_HALF_UP),
                    manufacturcost.setScale(2, BigDecimal.ROUND_HALF_UP),
                    mancost.setScale(2, BigDecimal.ROUND_HALF_UP),
                    othercost.setScale(2, BigDecimal.ROUND_HALF_UP),
                    costAllocationOrder.getId());
            jdbcTemplate.execute(sql);

            sql="{call MP_SP_direct_material(?)}";
            paramMap.put("currUserID",systemConfig.getUserid());
            runPDSQL(sql,paramMap);
            paramMap.clear();

            sql="{call MP_SP_CostAllocationOrderSave(?,?,?)}";//"exec  @voucherId=52,@currUserID=18,@newID=52"
            paramMap.put("voucherId",costAllocationOrder.getId());
            paramMap.put("currUserID",systemConfig.getUserid());
            paramMap.put("newID",costAllocationOrder.getId());
            runPDSQL(sql,paramMap);
            paramMap.clear();

//            sql="{call MP_SP_CostAllocationOrderToTmp(?,?)}";
//            paramMap.put("voucherId",costAllocationOrder.getId());
//            paramMap.put("currUserID",systemConfig.getUserid());
//            runPDSQL(sql,paramMap);
//            paramMap.clear();
            resultInfo.setData(costAllocationOrder);
            resultInfo.setResultCode(ResultCode.SUCCESS);

        }catch (Exception ex){
            ex.printStackTrace();
            resultInfo.setErrorMessage("导入失败，异常信息："+ex.getMessage());
            throw new RuntimeException("数据库执行失败");
        }
        return resultInfo;
    }

    public void updateCostAllocationOrderDetailsInfo(List<CostAllocationOrderDetails> costAllocationOrderDetailsList,Integer orderId ){
        //更新子表
        //1、获取子表信息
        List<CostAllocationOrderDetails> updateCostAllocationOrderDetailsList=getCostAllocationOrderDetailsByMainId(orderId);
        List<Object[]> params=new ArrayList<>();
        for (CostAllocationOrderDetails data:costAllocationOrderDetailsList) {
            CostAllocationOrderDetails updateData=updateCostAllocationOrderDetailsList.stream().filter(
                    p->p.getJgdcode().equals(data.getJgdcode())
                            && p.getIdinventory().intValue()==data.getIdinventory()
            ).findFirst().get();
            updateData.setDirectmaterials(data.getDirectmaterials());
            updateData.setIndirectmaterials(data.getIndirectmaterials());
            updateData.setManufacturecost(data.getManufacturecost());
            updateData.setMancost(data.getMancost());
            updateData.setOthercost(data.getOthercost());
            updateData.setTotalcost(data.getTotalcost());
            updateData.setUnitcost(data.getUnitcost());

            Object[] childParams=new Object[8];
            childParams[0]=updateData.getDirectmaterials().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[1]=updateData.getIndirectmaterials().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[2]=updateData.getManufacturecost().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[3]=updateData.getMancost().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[4]=updateData.getOthercost().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[5]=updateData.getTotalcost().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[6]=updateData.getUnitcost().setScale(2, BigDecimal.ROUND_HALF_UP);
            childParams[7]=updateData.getId();
            params.add(childParams);

        }


        String sql="UPDATE MP_CostAllocationOrder_b " +
                " SET  directmaterials=?, indirectmaterials=?, manufacturecost=?," +
                " mancost=?, outsourcingcost=0, othercost=?, othercost1=0, othercost2=0," +
                " totalcost=?, unitcost=? " +
                " WHERE id=?";


        jdbcTemplate.batchUpdate(sql,params);
    }

    /**
     * 获取生产成本分配单明细信息
     * @param orderId
     * @return
     */
    public List<CostAllocationOrderDetails> getCostAllocationOrderDetailsByMainId(Integer orderId){
        String sql="select id,jgdcode,idinventory from MP_CostAllocationOrder_b where idCostAllocationOrderDTO="+orderId ;
        return (List<CostAllocationOrderDetails>) jdbcTemplate.query(sql, new RowMapper<CostAllocationOrderDetails>(){
            @Override
            public CostAllocationOrderDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
                ResultSetMetaData rSetMetaData=rs.getMetaData();
                Map<String, Object> maps=new HashMap<String, Object>();
                CostAllocationOrderDetails costAllocationOrderDetails = new CostAllocationOrderDetails();
                for(int i=0;i<rSetMetaData.getColumnCount();i++){
                    String columnLabel=rSetMetaData.getColumnLabel(i+1);
                    Object columnValue=rs.getObject(i+1);
                    maps.put(columnLabel,columnValue);
                }
                if(maps.size()>0){
                    for(Map.Entry<String,Object> entry:maps.entrySet()){
                        String fieldName=entry.getKey();
                        Object fieldValue=entry.getValue();
                        ReflectionUtils.setFieldValue(costAllocationOrderDetails, fieldName, fieldValue);
                    }
                }
                return costAllocationOrderDetails;
            }
        });
    }

    public CostAllocationOrder createCostAllocationOrder(
            String orderCode,java.util.Date orderDate,
            BigDecimal directmaterialcost, BigDecimal indirectmaterialcost,BigDecimal manufacturcost,BigDecimal mancost,BigDecimal othercost){
        //1.创建主表信息
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMddhhmmss");
        CostAllocationOrder costAllocationOrder = new CostAllocationOrder();
        costAllocationOrder.setCode(orderCode);
        costAllocationOrder.setAccountingperiod(orderDate.getMonth()+1);
        costAllocationOrder.setAccountingyear(orderDate.getYear()+1900);
        costAllocationOrder.setMaker("chen");
        //间接材料
        costAllocationOrder.setIndirectmaterialcost(indirectmaterialcost);
        //直接材料
        costAllocationOrder.setDirectmaterialcost(directmaterialcost);
        //制造费用
        costAllocationOrder.setManufacturcost(manufacturcost);
        //人工费用
        costAllocationOrder.setMancost(mancost);
        //委外费用
        //costAllocationOrder.setConsignationcost(new BigDecimal(1000));
        //其他费用
        costAllocationOrder.setOthercost(othercost);
        //其他费用1
        //costAllocationOrder.setOthercost1(new BigDecimal(1000));
        //其他费用2
        //costAllocationOrder.setOthercost2(new BigDecimal(1000));
        //分摊依据
        costAllocationOrder.setAllocationbasis(2090);
        //归集对象
        costAllocationOrder.setCostcollectorobject(2088);
        //单据状态
        costAllocationOrder.setVoucherstate(181);
        //制单人ID
        costAllocationOrder.setMakerid(systemConfig.getUserid());
        costAllocationOrder.setVoucherdate(orderDate);
        costAllocationOrder.setMadedate(orderDate);
        costAllocationOrder.setCreatedtime(orderDate);

        String sql = "INSERT INTO MP_CostAllocationOrder " +
                "(code, accountingperiod, accountingyear, maker, " +
                "directmaterialcost," +
                " indirectmaterialcost, manufacturcost, mancost, othercost, " +
                "allocationbasis, costcollectorobject, voucherstate," +
                "makerid, voucherdate, madedate, createdtime)" +
                "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        Object[] mainParam = new Object[16];
        mainParam[0]=costAllocationOrder.getCode();
        mainParam[1]=costAllocationOrder.getAccountingperiod();
        mainParam[2]=costAllocationOrder.getAccountingyear();
        mainParam[3]=costAllocationOrder.getMaker();
        mainParam[4]=costAllocationOrder.getDirectmaterialcost().setScale(2, BigDecimal.ROUND_HALF_UP);
        mainParam[5]=costAllocationOrder.getIndirectmaterialcost().setScale(2, BigDecimal.ROUND_HALF_UP);
        mainParam[6]=costAllocationOrder.getManufacturcost().setScale(2, BigDecimal.ROUND_HALF_UP);
        mainParam[7]=costAllocationOrder.getMancost().setScale(2, BigDecimal.ROUND_HALF_UP);
        mainParam[8]=costAllocationOrder.getOthercost().setScale(2, BigDecimal.ROUND_HALF_UP);
        mainParam[9]=costAllocationOrder.getAllocationbasis();
        mainParam[10]=costAllocationOrder.getCostcollectorobject();
        mainParam[11]=costAllocationOrder.getVoucherstate();
        mainParam[12]=costAllocationOrder.getMakerid();
        mainParam[13]=costAllocationOrder.getVoucherdate();
        mainParam[14]=costAllocationOrder.getMadedate();
        mainParam[15]=costAllocationOrder.getCreatedtime();
        Integer flag=jdbcTemplate.update(sql,mainParam);
        if(flag>0){
            costAllocationOrder=getCostAllocationOrderByCode(costAllocationOrder.getCode());
        }else{
            costAllocationOrder=null;
        }
        return  costAllocationOrder;
    }


    public void getZZCL(){
        String sql="{call MP_SP_direct_material(?)}";

        jdbcTemplate.execute(sql, new CallableStatementCallback<Object>() {
            @Override
            public Object doInCallableStatement(CallableStatement callableStatement) throws SQLException, DataAccessException {
                callableStatement.setInt(1,systemConfig.getUserid()); //设置参数
                callableStatement.execute();
                return null;
            }
        });
    }

    public CostAllocationOrder getCostAllocationOrderByCode(String code) {
        String sql = "SELECT code, docno, docclass, accountingperiod, docid, accountingyear, memo," +
                " maker,  reviser, directmaterialcost," +
                " indirectmaterialcost, manufacturcost, mancost, consignationcost, othercost, othercost1, othercost2," +
                "  PrintCount, id, idmarketingorgan, idperson, idproject, allocationbasis, costcollectorobject, " +
                "voucherstate, makerid, voucherdate, madedate,  createdtime " +
                " FROM MP_CostAllocationOrder where code='"+code+"'";

        return (CostAllocationOrder) jdbcTemplate.query(sql, new RowMapper<CostAllocationOrder>(){
            @Override
            public CostAllocationOrder mapRow(ResultSet rs, int rowNum) throws SQLException {
                ResultSetMetaData rSetMetaData=rs.getMetaData();
                Map<String, Object> maps=new HashMap<String, Object>();
                CostAllocationOrder costAllocationOrder = new CostAllocationOrder();
                for(int i=0;i<rSetMetaData.getColumnCount();i++){
                    String columnLabel=rSetMetaData.getColumnLabel(i+1);
                    Object columnValue=rs.getObject(i+1);
                    maps.put(columnLabel,columnValue);
                }
                if(maps.size()>0){
                    for(Map.Entry<String,Object> entry:maps.entrySet()){
                        String fieldName=entry.getKey();
                        Object fieldValue=entry.getValue();
                        ReflectionUtils.setFieldValue(costAllocationOrder, fieldName, fieldValue);
                    }
                }
                return costAllocationOrder;
            }
        }).get(0);
    }

    public List<CostAllocationOrder> getList(){
        String sql = "SELECT code, docno, docclass, accountingperiod, docid, accountingyear, memo," +
                " maker,  reviser,  directmaterialcost," +
                " indirectmaterialcost, manufacturcost, mancost, consignationcost, othercost, othercost1, othercost2," +
                "  PrintCount, id, idmarketingorgan, idperson, idproject, allocationbasis, costcollectorobject, " +
                "voucherstate, makerid, voucherdate, madedate,  createdtime " +
                " FROM MP_CostAllocationOrder";


        return (List<CostAllocationOrder>) jdbcTemplate.query(sql, new RowMapper<CostAllocationOrder>(){
            @Override
            public CostAllocationOrder mapRow(ResultSet rs, int rowNum) throws SQLException {
                ResultSetMetaData rSetMetaData=rs.getMetaData();
                Map<String, Object> maps=new HashMap<String, Object>();
                CostAllocationOrder costAllocationOrder = new CostAllocationOrder();
                for(int i=0;i<rSetMetaData.getColumnCount();i++){
                    String columnLabel=rSetMetaData.getColumnLabel(i+1);
                    Object columnValue=rs.getObject(i+1);
                    maps.put(columnLabel,columnValue);
                }
                if(maps.size()>0){
                    for(Map.Entry<String,Object> entry:maps.entrySet()){
                        String fieldName=entry.getKey();
                        Object fieldValue=entry.getValue();
                        ReflectionUtils.setFieldValue(costAllocationOrder, fieldName, fieldValue);
                    }
                }
                return costAllocationOrder;
            }
        });
    }
}
